package com.myk.game.gobangchess.rooms;

import com.myk.game.gobangchess.Room;
import com.myk.game.gobangchess.Sign;
import com.myk.game.gobangchess.constants.ColorCost;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.rooms.absrooms.movechess.MoreColorCost;
import com.myk.game.gobangchess.rooms.absrooms.movechess.MovedChess;
import com.myk.game.gobangchess.rooms.absrooms.movechess.MovedChessRoom;
import com.myk.game.gobangchess.signs.*;
import com.myk.game.gobangchess.utils.GridsUtils;
import com.myk.game.gobangchess.utils.Pair;

import java.util.ArrayList;
import java.util.List;

/**
 * 战国象棋
 */
public class ZhanGuoXiangQiRoom extends Room implements MovedChessRoom {

    private CacheSign cacheSign;
    private final List<MovedChess> chessList = new ArrayList<>();
    private final List<int[]> moveArrayList = new ArrayList<>(2); // 走子标记
    private MovedChess selectedChess;
    private ThreeLoopQueue threeLoopQueue; //循环判断器


    public ZhanGuoXiangQiRoom(String roomName) {
        super(roomName, "新棋吧友愚人之心的新七国象棋(战国象棋)。", "战国象棋", GridsUtils.createEmptyGrids(9, 9), true, true);
        initBackground();
    }

    private void initBackground() {
        List<Sign> chessboardStyle = new ArrayList<>();
        int maxRow = curGrids.length - 1;
        int maxCol = curGrids[0].length - 1;
        //背景
        chessboardStyle.add(new GroundSign(getIndex(0, 0), getIndex(maxRow, maxCol), ColorCost.TABLECLOTH_COLOR, ColorCost.TABLECLOTH_COLOR, 2f, 0, 0));
        //外边框
        chessboardStyle.add(getPath(0, 0, 0, maxCol, 1));
        chessboardStyle.add(getPath(maxRow, 0, maxRow, maxCol, 1));
        chessboardStyle.add(getPath(0, 0, maxRow, 0, 1));
        chessboardStyle.add(getPath(0, maxCol, maxRow, maxCol, 1));
        //线条
        for (int i = 1; i < maxRow; i++) {
            chessboardStyle.add(getPath(i, 0, i, maxCol, 1));
        }
        for (int i = 1; i < maxCol; i++) {
            chessboardStyle.add(getPath(0, i, maxRow, i, 1));
        }
        //中心点
        chessboardStyle.add(new BadgeSign(getIndex(4, 4), "",4,ColorCost.TABLECLOTH_COLOR,MoreColorCost.BOARD_LINE));
        //添加到缓存标记
        cacheSign = new CacheSign(this, "background", 12, true, chessboardStyle); //*** 修改背景样式记得改这里的版本号！！！
    }

    private PathSign getPath(final int fRow, final int fCol, final int tRow, final int tCol, final float size) {
        List<Pair<Integer, Integer>> nodes = new ArrayList<>();
        nodes.add(new Pair<>(getIndex(fRow, fCol), 4));
        nodes.add(new Pair<>(getIndex(tRow, tCol), 4));
        return new PathSign(nodes, MoreColorCost.BOARD_LINE, MoreColorCost.BOARD_LINE, size, 0);
    }

    @Override
    public CacheSign getCacheSignByName(String cacheName) {
        return cacheSign;
    }

    @Override
    public String getCoordMode() {
        return "35000000";
    }

    @Override
    public String getGameInfo() {
        //先清空棋盘
        curGrids = GridsUtils.copyGrids(originGrids);
        signList.clear();
        signList.add(cacheSign);
        this.render();
        //画一下箭头
        for (int[] moveArray : moveArrayList) {
            signList.add(new LineSign(moveArray[0], moveArray[1], ColorCost.MOVE_ARROW_LIGHT, 1));
        }
        return super.getGameInfo();
    }


    @Override
    public void resetGrids() {
        super.resetGrids();
        chessList.clear();
        selectedChess = null;
        moveArrayList.clear();
    }

    @Override
    protected void onStartPrepare() {
        initChess();
        //initTestChess();
        threeLoopQueue = new ThreeLoopQueue();
        noticeBlackMove(); //默认通知黑方先行动
    }

    private void initTestChess() {
        chessList.clear();
        // 将
        chessList.add(new General(1, 0, 4));
        chessList.add(new General(2, 8, 4));
        //骑
        chessList.add(new Horse(1, 4, 4));
        chessList.add(new Horse(1, 3, 4));
    }

    private void initChess() {
        chessList.clear();
        // 剑
        chessList.add(new Pawn(1, 2, 0));
        chessList.add(new Pawn(1, 2, 2));
        chessList.add(new Pawn(1, 2, 6));
        chessList.add(new Pawn(1, 2, 8));
        chessList.add(new Pawn(2, 6, 0));
        chessList.add(new Pawn(2, 6, 2));
        chessList.add(new Pawn(2, 6, 6));
        chessList.add(new Pawn(2, 6, 8));

        //人
        chessList.add(new Person(1, 2, 4));
        chessList.add(new Person(2, 6, 4));

        // 刀
        chessList.add(new Guard(1, 1, 1));
        chessList.add(new Guard(1, 1, 7));
        chessList.add(new Guard(2, 7, 1));
        chessList.add(new Guard(2, 7, 7));

        // 炮
        chessList.add(new Cannon(1, 1, 4));
        chessList.add(new Cannon(2, 7, 4));

        // 骑
        chessList.add(new Horse(1, 0, 0));
        chessList.add(new Horse(1, 0, 1));
        chessList.add(new Horse(1, 0, 7));
        chessList.add(new Horse(1, 0, 8));
        chessList.add(new Horse(2, 8, 0));
        chessList.add(new Horse(2, 8, 1));
        chessList.add(new Horse(2, 8, 7));
        chessList.add(new Horse(2, 8, 8));

        //弓
        chessList.add(new Arch(1, 0, 6));
        chessList.add(new Arch(2, 8, 2));

        // 弩
        chessList.add(new Crossbow(1, 0, 2));
        chessList.add(new Crossbow(2, 8, 6));

        //偏
        chessList.add(new Chariot(1, 0, 5));
        chessList.add(new Chariot(2, 8, 3));

        //裨
        chessList.add(new Bishop(1, 0, 3));
        chessList.add(new Bishop(2, 8, 5));

        // 将
        chessList.add(new General(1, 0, 4));
        chessList.add(new General(2, 8, 4));

    }

    private String serializeChessList() {
        StringBuilder sb = new StringBuilder();
        for (MovedChess movedChess : chessList) {
            sb.append(movedChess.getName()).append(movedChess.getSide()).append(movedChess.getRow()).append(movedChess.getCol());
        }
        return sb.toString();
    }

    @Override
    public String getRuleText() {
        return "规则\n" +
                "1、将（国名）直走横走斜走一步。\n" +
                "2、偏直走横走，不限远近。\n" +
                "3、裨斜走，不限远近。\n" +
                "4、弩最多直走横走斜走四步。\n" +
                "5、弓最多直走横走斜走三步。\n" +
                "6、骑走曲线直一斜二，中途不可越子。即朝鲜象棋马与象的合体。\n" +
                "7、炮直走横走不限远近，吃子时，需前方隔一子方可吃子。\n" +
                "8、行人直走横走一步，不可吃子也不能被吃，但可以被对方棋子围死。\n" +
                "9、剑直走横走一步。\n" +
                "10、刀斜走一步。\n" +
                "11、将一走入城（中心点），不需要将死对方获胜。\n" +
                "12、将死对方或让对方无棋可走获胜；同一局面重复三次和棋。";
    }

    private int getNextCur(int value) {
        return 3-value;
    }

    @Override
    public void doRule(int row, int col, int value) {
        if (selectOrMove(row, col, value)) {
            stepAdd();
            // 判断下一手是否无棋可走
            boolean canMove = false;
            // 判断帅是否走入了城
            boolean isInCity = false;
            // 判断是否吃了对方的帅
            int countGeneral = 0;
            for (MovedChess chess : chessList) {
                if (chess instanceof General) {
                    countGeneral++;
                    if (chess.getCol() == 4 && chess.getRow() == 4){
                        isInCity = true;
                    }
                }
                if (chess.getSide() == getNextCur(value) && (!chess.getMoveRange(this).isEmpty() || !chess.getEatRange(this).isEmpty())) {
                    canMove = true;
                }
            }
            if (isInCity){
                if (cur == 1) {
                    doOver(WinMode.BLACK_WIN, "黑方将入城获胜");
                }
                else {
                    doOver(WinMode.WHITE_WIN, "白方将入城获胜");
                }
                return;
            }
            if (countGeneral < 2) {
                if (cur == 1) {
                    doOver(WinMode.BLACK_WIN, "黑方杀王白方");
                }
                else {
                    doOver(WinMode.WHITE_WIN, "白方杀王黑方");
                }
                return;
            }
            if (!canMove) {
                if (cur == 1) {
                    doOver(WinMode.BLACK_WIN, "黑方闷杀白方");
                }
                else {
                    doOver(WinMode.WHITE_WIN, "白方闷杀黑方");
                }
                return;
            }

            //循环判和
            threeLoopQueue.enqueue(serializeChessList());
            if (threeLoopQueue.isThreeLoop()){
                doOver(WinMode.BOTH_DRAW, "连续三次相同局面和棋");
                return;
            }

            //切换行动方
            if (value == 1){
                noticeWhiteMove();
            }
            else {
                noticeBlackMove();
            }

        }
        else {
            noticeAllRefreshGameInfo();//通知界面刷新
        }
    }

    /**
     * 选择或走子
     *
     * @param row 点击位置的row
     * @param col 点击位置的col
     * @return 是否走子成功
     */
    private boolean selectOrMove(int row, int col, int value) {
        MovedChess target = getChessByPos(row, col);
        if (target == null && selectedChess == null) {
            // 既没有点击棋子，又没有已选中的棋子
            return false;
        }
        if (selectedChess == null) {
            if (target.getSide() != value){
                return false;
            }
            selectedChess = target;
            return false;
        }
        if (selectedChess == target) {
            // 取消选中棋子
            selectedChess = null;
            noticeAllRefreshGameInfo();
            return false;
        }
        if (selectedChess.getSide() != cur) {
            // 选中的是对方的棋子，仅能查看，不能移动
            // 取消选中棋子
            selectedChess = null;
            noticeAllRefreshGameInfo();
            return false;
        }
        // 尝试走子
        int startIndex = getIndex(selectedChess.getRow(), selectedChess.getCol());
        int endIndex = getIndex(row, col);
        if (selectedChess.getMoveRange(this).contains(endIndex)) {
            selectedChess.moveTo(row, col);
            checkAroundPerson(); //判断棋子人是否被围死
            moveArrayList.clear();
            moveArrayList.add(new int[]{startIndex, endIndex});
            selectedChess = null;
            return true;
        }
        else if (selectedChess.getEatRange(this).contains(endIndex)) {
            chessList.remove(getChessByPos(row, col));
            selectedChess.moveTo(row, col);
            moveArrayList.clear();
            moveArrayList.add(new int[]{startIndex, endIndex});
            selectedChess = null;
            return true;
        }
        else {
            selectedChess = null;
            return false;
        }
    }

    private void checkAroundPerson() {
        for (MovedChess movedChess : chessList) {
            if (movedChess instanceof Person){
                if (((Person) movedChess).isAroundEnemy(this)){
                    chessList.remove(movedChess);
                    return;
                }
            }
        }
    }

    @Override
    public List<MovedChess> getChessList() {
        return chessList;
    }

    @Override
    public MovedChess getSelectedChess() {
        return selectedChess;
    }

    @Override
    public int[][] getCurGrids() {
        return curGrids;
    }

    @Override
    public List<Sign> getSignList() {
        return signList;
    }

    @Override
    public MovedChess getChessByPos(int row, int col) {
        for (MovedChess chess : chessList) {
            if (chess.getRow() == row && chess.getCol() == col) {
                return chess;
            }
        }
        return null;
    }

    @Override
    public MovedChess getChessByIndex(int index) {
        for (MovedChess chess : chessList) {
            if (chess.getIndex(this) == index) {
                return chess;
            }
        }
        return null;
    }

    public static abstract class Chess implements MovedChess {
        public int row;
        public int col;
        private final int side;
        private final String name;

        public Chess(String name, int side, int row, int col) {
            this.name = name;
            this.side = side;
            this.row = row;
            this.col = col;
        }

        @Override
        public String getColor() {
            return getSide() == 1 ? MoreColorCost.RED_CHESS_WORD : MoreColorCost.WHITE_CHESS_WORD;
        }

        protected int getDirection() {
            if (getSide() == 1) {
                return 1;
            }
            else if (getSide() == 2) {
                return -1;
            }
            else {
                return 0;
            }
        }

        protected boolean inSelfBoard() {
            if (getSide() == 1) {
                return getRow() <= 4;
            }
            else {
                return getRow() >= 5;
            }
        }

        protected boolean inEnemyBoard() {
            if (getSide() == 1) {
                return getRow() >= 5;
            }
            else {
                return getRow() <= 4;
            }
        }

        @Override
        public int getRow() {
            return row;
        }

        @Override
        public int getCol() {
            return col;
        }

        @Override
        public void moveTo(int row, int col) {
            this.row = row;
            this.col = col;
        }

        @Override
        public int getSide() {
            return side;
        }

        @Override
        public String getName() {
            return name;
        }
    }

    /**
     * 将（国名）直走横走斜走一步。
     */
    private static class General extends Chess {
        public General(int mSide, int pRow, int pCol) {
            super("将", mSide, pRow, pCol);
        }

        @Override
        public String getName() {
            return getSide() == 1 ? "秦" : "楚";
        }

        @Override
        public List<Integer> getMoveRange(MovedChessRoom room) {
            return genMoveRange(room, new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1},{1,1},{-1,1},{1,-1},{-1,-1}}, 1);
        }

        @Override
        public List<Integer> getEatRange(MovedChessRoom room) {
            List<Integer> range = genEatRange(room, new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1},{1,1},{-1,1},{1,-1},{-1,-1}}, 1);
            range.removeIf(i -> room.getChessByIndex(i) instanceof Person); //不能吃行人棋子
            return range;
        }
    }

    /**
     * 偏直走横走，不限远近。
     */
    private static class Chariot extends Chess {
        public Chariot(int mSide, int pRow, int pCol) {
            super("偏", mSide, pRow, pCol);
        }

        @Override
        public String getName() {
            return "偏";
        }

        @Override
        public List<Integer> getMoveRange(MovedChessRoom room) {
            return genMoveRange(room, new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}, Integer.MAX_VALUE);
        }

        @Override
        public List<Integer> getEatRange(MovedChessRoom room) {
            List<Integer> range =  genEatRange(room, new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}, Integer.MAX_VALUE);
            range.removeIf(i -> room.getChessByIndex(i) instanceof Person); //不能吃行人棋子
            return range;
        }
    }

    /**
     * 裨斜走，不限远近。
     */
    private static class Bishop extends Chess {
        public Bishop(int mSide, int pRow, int pCol) {
            super("裨", mSide, pRow, pCol);
        }

        @Override
        public String getName() {
            return "裨";
        }

        @Override
        public List<Integer> getMoveRange(MovedChessRoom room) {
            List<Integer> range = genMoveRange(room, new int[][]{{1, 1}, {-1, 1}, {-1, -1}, {1, -1}}, Integer.MAX_VALUE);
            return range;
        }

        @Override
        public List<Integer> getEatRange(MovedChessRoom room) {
            List<Integer> range = genEatRange(room, new int[][]{{1, 1}, {-1, 1}, {-1, -1}, {1, -1}}, Integer.MAX_VALUE);
            range.removeIf(i -> room.getChessByIndex(i) instanceof Person); //不能吃行人棋子
            return range;
        }
    }

    /**
     * 弩最多直走横走斜走四步。
     */
    private static class Crossbow extends Chess {
        public Crossbow(int mSide, int pRow, int pCol) {
            super("弩", mSide, pRow, pCol);
        }

        @Override
        public String getName() {
            return "弩";
        }

        @Override
        public List<Integer> getMoveRange(MovedChessRoom room) {
            return genMoveRange(room, new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1},{1,1},{-1,1},{1,-1},{-1,-1}}, 4);
        }

        @Override
        public List<Integer> getEatRange(MovedChessRoom room) {
            List<Integer> range = genEatRange(room, new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1},{1,1},{-1,1},{1,-1},{-1,-1}}, 4);
            range.removeIf(i -> room.getChessByIndex(i) instanceof Person); //不能吃行人棋子
            return range;
        }
    }

    /**
     * 弓最多直走横走斜走三步。
     */
    private static class Arch extends Chess {
        public Arch(int mSide, int pRow, int pCol) {
            super("弓", mSide, pRow, pCol);
        }

        @Override
        public String getName() {
            return "弓";
        }

        @Override
        public List<Integer> getMoveRange(MovedChessRoom room) {
            return genMoveRange(room, new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1},{1,1},{-1,1},{1,-1},{-1,-1}}, 3);
        }

        @Override
        public List<Integer> getEatRange(MovedChessRoom room) {
            List<Integer> range = genEatRange(room, new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1},{1,1},{-1,1},{1,-1},{-1,-1}}, 3);
            range.removeIf(i -> room.getChessByIndex(i) instanceof Person); //不能吃行人棋子
            return range;
        }
    }

    /**
     * 骑走曲线直一斜二，中途不可越子。即朝鲜象棋马与象的合体。
     */
    private static class Horse extends Chess {
        public Horse(int mSide, int pRow, int pCol) {
            super("骑", mSide, pRow, pCol);
        }

        @Override
        public String getName() {
            return "骑";
        }

        @Override
        public List<Integer> getMoveRange(MovedChessRoom room) {
            List<Integer> range = new ArrayList<>();
            if (room.getChessByPos(getRow() + 1, getCol()) == null) {
                range.addAll(genMoveRange(room, new int[][]{{2, 1}, {2, -1}}, 1));
                if (room.getChessByPos(getRow() + 2, getCol()-1) == null){
                    range.addAll(genMoveRange(room, new int[][]{{3, -2}}, 1));
                }
                if (room.getChessByPos(getRow() + 2, getCol()+1) == null){
                    range.addAll(genMoveRange(room, new int[][]{{3, 2}}, 1));
                }
            }
            if (room.getChessByPos(getRow() - 1, getCol()) == null) {
                range.addAll(genMoveRange(room, new int[][]{{-2, 1}, {-2, -1}}, 1));
                if (room.getChessByPos(getRow() - 2, getCol()-1) == null){
                    range.addAll(genMoveRange(room, new int[][]{{-3, -2}}, 1));
                }
                if (room.getChessByPos(getRow() - 2, getCol()+1) == null){
                    range.addAll(genMoveRange(room, new int[][]{{-3, 2}}, 1));
                }
            }
            if (room.getChessByPos(getRow(), getCol() + 1) == null) {
                range.addAll(genMoveRange(room, new int[][]{{1, 2}, {-1, 2}}, 1));
                if (room.getChessByPos(getRow() + 1, getCol()+2) == null){
                    range.addAll(genMoveRange(room, new int[][]{{2, 3}}, 1));
                }
                if (room.getChessByPos(getRow() - 1, getCol()+2) == null){
                    range.addAll(genMoveRange(room, new int[][]{{-2, 3}}, 1));
                }
            }
            if (room.getChessByPos(getRow(), getCol() - 1) == null) {
                range.addAll(genMoveRange(room, new int[][]{{1, -2}, {-1, -2}}, 1));
                if (room.getChessByPos(getRow() + 1, getCol()-2) == null){
                    range.addAll(genMoveRange(room, new int[][]{{2, -3}}, 1));
                }
                if (room.getChessByPos(getRow() - 1, getCol()-2) == null){
                    range.addAll(genMoveRange(room, new int[][]{{-2, -3}}, 1));
                }
            }
            return range;
        }

        @Override
        public List<Integer> getEatRange(MovedChessRoom room) {
            List<Integer> range = new ArrayList<>();
            if (room.getChessByPos(getRow() + 1, getCol()) == null) {
                range.addAll(genEatRange(room, new int[][]{{2, 1}, {2, -1}}, 1));
                if (room.getChessByPos(getRow() + 2, getCol()-1) == null){
                    range.addAll(genEatRange(room, new int[][]{{3, -2}}, 1));
                }
                if (room.getChessByPos(getRow() + 2, getCol()+1) == null){
                    range.addAll(genEatRange(room, new int[][]{{3, 2}}, 1));
                }
            }
            if (room.getChessByPos(getRow() - 1, getCol()) == null) {
                range.addAll(genEatRange(room, new int[][]{{-2, 1}, {-2, -1}}, 1));
                if (room.getChessByPos(getRow() - 2, getCol()-1) == null){
                    range.addAll(genEatRange(room, new int[][]{{-3, -2}}, 1));
                }
                if (room.getChessByPos(getRow() - 2, getCol()+1) == null){
                    range.addAll(genEatRange(room, new int[][]{{-3, 2}}, 1));
                }
            }
            if (room.getChessByPos(getRow(), getCol() + 1) == null) {
                range.addAll(genEatRange(room, new int[][]{{1, 2}, {-1, 2}}, 1));
                if (room.getChessByPos(getRow() + 1, getCol()+2) == null){
                    range.addAll(genEatRange(room, new int[][]{{2, 3}}, 1));
                }
                if (room.getChessByPos(getRow() - 1, getCol()+2) == null){
                    range.addAll(genEatRange(room, new int[][]{{-2, 3}}, 1));
                }
            }
            if (room.getChessByPos(getRow(), getCol() - 1) == null) {
                range.addAll(genEatRange(room, new int[][]{{1, -2}, {-1, -2}}, 1));
                if (room.getChessByPos(getRow() + 1, getCol()-2) == null){
                    range.addAll(genEatRange(room, new int[][]{{2, -3}}, 1));
                }
                if (room.getChessByPos(getRow() - 1, getCol()-2) == null){
                    range.addAll(genEatRange(room, new int[][]{{-2, -3}}, 1));
                }
            }
            range.removeIf(i -> room.getChessByIndex(i) instanceof Person);//不能吃行人棋子
            return range;
        }
    }

    /**
     * 炮直走横走不限远近，吃子时，需前方隔一子方可吃子。
     */
    private static class Cannon extends Chess {
        public Cannon(int mSide, int pRow, int pCol) {
            super("炮", mSide, pRow, pCol);
        }

        @Override
        public String getName() {
            return "炮";
        }

        @Override
        public List<Integer> getMoveRange(MovedChessRoom room) {
            return genMoveRange(room, new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}, Integer.MAX_VALUE);
        }

        @Override
        public List<Integer> getEatRange(MovedChessRoom room) {
            List<Integer> range = genEatRange(room, new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}, Integer.MAX_VALUE, 1, 1);
            range.removeIf(i -> room.getChessByIndex(i) instanceof Person); //不能吃行人棋子
            return range;
        }
    }

    /**
     * 行人直走横走一步，不可吃子也不能被吃，但可以被对方棋子围死。
     */
    private static class Person extends Chess {
        public Person(int mSide, int pRow, int pCol) {
            super("人", mSide, pRow, pCol);
        }

        @Override
        public String getName() {
            return "人";
        }

        @Override
        public List<Integer> getMoveRange(MovedChessRoom room) {
            return genMoveRange(room, new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}, 1);
        }

        @Override
        public List<Integer> getEatRange(MovedChessRoom room) {
            List<Integer> range = genEatRange(room, new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}, 1);
            range.removeIf(i -> room.getChessByIndex(i) != null); //不能吃子
            return range;
        }

        public boolean isAroundEnemy(MovedChessRoom room) {
            int maxRow = room.getCurGrids().length-1;
            int maxCol = room.getCurGrids()[0].length-1;
            List<Integer> range = new ArrayList<>(4);
            if (row>0){
                range.add(room.getIndex(row-1,col));
            }
            if (row<maxRow){
                range.add(room.getIndex(row+1,col));
            }
            if (col>0){
                range.add(room.getIndex(row,col-1));
            }
            if (col<maxCol){
                range.add(room.getIndex(row,col+1));
            }
            return range.stream().allMatch(i->room.getChessByIndex(i)!=null&&room.getChessByIndex(i).getSide()!= this.getSide());
        }
    }

    /**
     * 剑直走横走一步
     */
    private static class Pawn extends Chess {
        public Pawn(int mSide, int pRow, int pCol) {
            super("剑", mSide, pRow, pCol);
        }

        @Override
        public String getName() {
            return "剑";
        }

        @Override
        public List<Integer> getMoveRange(MovedChessRoom room) {
            return genMoveRange(room, new int[][]{{1, 0},{-1, 0}, {0, 1}, {0, -1}}, 1);
        }

        @Override
        public List<Integer> getEatRange(MovedChessRoom room) {
            List<Integer> range = genEatRange(room, new int[][]{{1, 0},{-1, 0}, {0, 1}, {0, -1}}, 1);
            range.removeIf(i -> room.getChessByIndex(i) instanceof Person);//不能吃行人棋子
            return range;
        }
    }

    /**
     * 刀斜走一步
     */
    private static class Guard extends Chess {
        public Guard(int mSide, int pRow, int pCol) {
            super("刀", mSide, pRow, pCol);
        }

        @Override
        public String getName() {
            return "刀";
        }

        @Override
        public List<Integer> getMoveRange(MovedChessRoom room) {
            return genMoveRange(room, new int[][]{{1, 1}, {-1, 1}, {-1, -1}, {1, -1}}, 1);
        }

        @Override
        public List<Integer> getEatRange(MovedChessRoom room) {
            List<Integer> range = genEatRange(room, new int[][]{{1, 1}, {-1, 1}, {-1, -1}, {1, -1}}, 1);
            range.removeIf(i -> room.getChessByIndex(i) instanceof Person);//不能吃行人棋子
            return range;
        }
    }

    /**
     * 三次循环判断器
     */
    public static class ThreeLoopQueue {
        private final String[] queue = new String[10];
        private int rear = 0;

        public void enqueue(String element) {
            if (rear == queue.length) {
                for (int i = 0; i < queue.length - 1; i++) {
                    queue[i] = queue[i + 1];
                }
                queue[queue.length-1] = element;
            }
            else {
                queue[rear] = element;
                rear++;
            }
        }

        public boolean isThreeLoop() {
            if (rear < queue.length){
                return false;
            }
            return queue[0].equals(queue[4]) && queue[1].equals(queue[5]) && queue[2].equals(queue[6]) && queue[3].equals(queue[7]) && queue[0].equals(queue[8]) && queue[1].equals(queue[9]);
        }

    }
}
